#pragma once
#include "GameModuleDependence.h"

namespace _MODULE_
{
	namespace _GAME_
	{
		/**
		    genaral iterator interface
		*/
		__interface iCommonActorIterate
		{
			iCommonActorIterate* Next();
			iCommonActorIterate* Prev();
			const ::_P_GAME::Actor* Get();
			/**
			    reset iterator.
				return value is false when a iterator is loaded.that is reset is noneed
		*/
			bool ReSet();
			bool IsReachedEnd();
			bool IsReachedBegin();
		};

		template<typename TypeOfContainer>
		class ActorIterator:
			public iCommonActorIterate
		{
			typedef typename TypeOfContainer::const_iterator TypeOfIterator;
		public:	
			    
			
				iCommonActorIterate* Next();
				iCommonActorIterate* Prev();
				const ::_P_GAME::Actor* Get();
				bool IsReachedEnd();
				bool IsReachedBegin();
				bool ReSet();
				void  Set( TypeOfIterator& iter );

				
				

		protected:
			ActorIterator(const TypeOfContainer *  ptrContainer)
			{
				m_ptrContainer = ptrContainer;
				m_Iterator = ptrContainer->begin();
			}
		private:
			const TypeOfContainer * m_ptrContainer;
			TypeOfIterator m_Iterator;
			TypeOfIterator m_SavedIterator;
			unsigned int m_uiContainerSizeWhenSave;

		};

		
		template<typename TypeOfContainer>
		iCommonActorIterate* ActorIterator<TypeOfContainer>::Next()
		{
			if(m_Iterator != m_ptrContainer->end())
				++m_Iterator;

			return this;
		}

		template<typename TypeOfContainer>
		iCommonActorIterate* ActorIterator<TypeOfContainer>::Prev()
		{

			if(m_Iterator != m_ptrContainer->begin())
				--m_Iterator;

			return this;
		}

		template<typename TypeOfContainer>
		const ::_P_GAME::Actor* ActorIterator<TypeOfContainer>::Get()
		{
			if(m_Iterator != m_ptrContainer->end())
				return *m_Iterator;
			else
				return NULL;
		}

		template<typename TypeOfContainer>
		bool ActorIterator<TypeOfContainer>::IsReachedEnd()
		{
			return (m_Iterator == m_ptrContainer->end());
		}

		template<typename TypeOfContainer>
		bool ActorIterator<TypeOfContainer>::IsReachedBegin()
		{
			return (m_Iterator == m_ptrContainer->begin());
		}

		template<typename TypeOfContainer>
		bool ActorIterator<TypeOfContainer>::ReSet()
		{
			if(m_ptrContainer->size()==m_uiContainerSizeWhenSave)
			{//just load saved iter
				m_Iterator = m_SavedIterator;
				return false;
			}
			else
			{// container is changed so do reset
				m_Iterator = m_ptrContainer->begin();
				m_SavedIterator = m_ptrContainer->end();
				m_uiContainerSizeWhenSave=0;
				return true;
			}
		}

		template<typename TypeOfContainer>
		void  ActorIterator<TypeOfContainer>::Set( TypeOfIterator& iter )
		{
			//check iter
			BOOST_MULTI_INDEX_CHECK_VALID_ITERATOR(iter);
			BOOST_MULTI_INDEX_CHECK_SAME_OWNER(iter,m_SavedIterator);
			
			//iter is valid
			m_SavedIterator = iter;

			m_uiContainerSizeWhenSave = m_ptrContainer->size();
		}
	}
}